package com.xc.ksxt.service;

import com.google.common.base.Optional;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Lists;
import com.xc.ksxt.entity.KnowledgePointEntity;
import com.xc.ksxt.entity.KnowledgePointEntity;
import com.xc.ksxt.vo.KnowledgePointVO;
import com.xc.common.object.PageInfo;
import com.xc.common.tool.BeanAid;
import com.xc.common.tool.Helper;
import com.xc.db.tables.KnowledgePoint;
import com.xc.db.tables.records.KnowledgePointRecord;
import java.util.List;
import java.util.concurrent.ExecutionException;

import org.apache.commons.lang3.StringUtils;
import org.jooq.Condition;
import org.jooq.DSLContext;
import org.jooq.Record;
import org.jooq.Result;
import org.jooq.SelectForUpdateStep;
import org.jooq.SelectSeekStepN;
import org.jooq.SortField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class KnowledgePointService {
    @Autowired
    private DSLContext dsl;
    private KnowledgePoint KLP = KnowledgePoint.KNOWLEDGE_POINT.as("KLP");
    public KnowledgePoint getTable() {
        return KLP;
    }
    public Result<Record> select(Condition whr, PageInfo<KnowledgePointEntity> pageInfo, SortField<?>... orderby) {
        SelectSeekStepN<Record> seek = dsl.select().from(KLP).where(whr).orderBy(orderby);
        Result<Record> result = null;
        if (pageInfo != null) {
            SelectForUpdateStep<Record> su = seek.limit(pageInfo.getLimit()).offset(pageInfo.getBeginNum());
            result = su.fetch();
        } else {
            result = seek.fetch();
        }
        if (pageInfo != null) {
            pageInfo.setResult(result);
            pageInfo.setList(result.into(KnowledgePointEntity.class));
        }
        return result;
    }
    public Result<Record> selectVO(Condition whr, PageInfo<KnowledgePointVO> pageInfo, SortField<?>... orderby) {
        SelectSeekStepN<Record> seek = dsl.select().from(KLP).where(whr).orderBy(orderby);
        Result<Record> result = null;
        if (pageInfo != null) {
            SelectForUpdateStep<Record> su = seek.limit(pageInfo.getLimit()).offset(pageInfo.getBeginNum());
            result = su.fetch();
        } else {
            result = seek.fetch();
        }
        if (pageInfo != null) {
            pageInfo.setResult(result);
            pageInfo.setList(result.into(KnowledgePointVO.class));
        }
        return result;
    }

    public List<KnowledgePointEntity> select(Condition whr, SortField<?>... orderby) {
        Result<Record> result = dsl.select().from(KLP).where(whr).orderBy(orderby).fetch();
        List<KnowledgePointEntity> list = Lists.newArrayList();
        if (result.size() > 0) {
            list = result.into(KnowledgePointEntity.class);
        }
        return list;
    }

    public Long count(Condition cond) {
        Long count = dsl.selectCount().from(KLP).where(cond).fetchOneInto(Long.class);
        return count;
    }

    public Record getRecordById(Long id) {
        Record record = dsl.select().from(KLP).where(KLP.ID.eq(id)).fetchOne();
        return record;
    }

    public KnowledgePointEntity getEntityById(Long id) {
        Record r = getRecordById(id);
        if(r==null) {
            return null;
        }
        KnowledgePointEntity entity = r.into(KnowledgePointEntity.class);
        return entity;
    }

    public String update(KnowledgePointEntity entity) {
        KnowledgePointRecord record = new KnowledgePointRecord();
        record.from(entity);
        dsl.executeUpdate(record);
        invalidateCache(entity.getId());
        return entity.getId();
    }

    public String insert(KnowledgePointEntity entity) {
        KnowledgePointRecord record = new KnowledgePointRecord();
        if(StringUtils.isEmpty(entity.getId())) {
            String id = Helper.getSnowId() + "";
            entity.setId(id);
        }
        record.from(entity);
        dsl.executeInsert(record);
        invalidateCache(entity.getId());
        return entity.getId();
    }

    public String save(KnowledgePointEntity entity) {
        if (entity.getId()==null||entity.getId().isEmpty()) {
            return insert(entity);
        }
        KnowledgePointEntity entity2 = getEntityById(Long.valueOf(entity.getId()));
        if(entity2==null) {
            return insert(entity);
        }
        return update(entity);
    }

    public void deleteById(Long id) {
        dsl.delete(KLP).where(KLP.ID.eq(id)).execute();
        invalidateCache(id);
    }
    public static LoadingCache<Long, Optional<KnowledgePointEntity>> cache = CacheBuilder.newBuilder().maximumSize(500).build(
            new CacheLoader<Long, Optional<KnowledgePointEntity>>() {
                public Optional<KnowledgePointEntity> load(Long id) {
                    KnowledgePointService service = BeanAid.getBean(KnowledgePointService.class);
                    KnowledgePointEntity user = service.getEntityById(id);
                    return Optional.fromNullable(user);
                }
            });
    public static KnowledgePointEntity getFromCaches(Long key) {
        if (key == null) {
            return null;
        }
        try {
            return cache.get(key).orNull();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return null;
    }
    public static KnowledgePointEntity getFromCaches(String key) {
        if (key == null) {
            return null;
        }
        try {
            return cache.get(Long.valueOf(key)).orNull();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return null;
    }
    public static void invalidateCache(String id) {
        cache.invalidate(Long.valueOf(id));
    }
    public static void invalidateCache(Long id) {
        cache.invalidate(id);
    }
}
